/***************************************************************************
 *  Filename: slavecommunicator.cpp
 *  Class: slavecommunicator
 *
 *  Copyright 2012  Xander van Kooten
 *  <xandervk@gmail.com>
 *
 *  Copyright 2012  Mario Henrique Voorsluys
 *  <forcaeluz@gmail.com>
 *
 ****************************************************************************/

/*
 *
 * This file is part of Parsax-Remote-Controller.
 *
 *    Parsax-Remote-Controller is free software: you can redistribute it
 *    and/or modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    Parsax-Remote-Controller is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Parsax-Remote-Controller.
 *    If not, see <http://www.gnu.org/licenses/>.
 */

#include "slavecommunicator.h"

SlaveCommunicator::SlaveCommunicator(QObject *parent):QObject(parent)
{
    openMasterConnection = 0;
}

SlaveCommunicator::~SlaveCommunicator(){
    if(openMasterConnection->isOpen()){
        openMasterConnection->close();
    }
    if(tcpListener.isListening()){
        tcpListener.close();
    }
}

void SlaveCommunicator::initialize(QString listenAddres, int port){
    if(tcpListener.isListening()){
        qDebug() << "[SlaveCommunicator] Changing listenAddress";
        tcpListener.close();
    }
    if(tcpListener.listen(QHostAddress(listenAddres), port)){
        qDebug() << "[SlaveCommunicator] tcpListener listening on " <<
                    tcpListener.serverAddress() << ":" << tcpListener.serverPort();
        connect(&tcpListener, SIGNAL(newConnection()), SLOT(setupConnection()), Qt::UniqueConnection);
    }else{
        qWarning() << "[SlaveCommunicator] Not able to listen";
    }

}

void SlaveCommunicator::sendData(QByteArray data){
    if(openMasterConnection==0){
        qWarning() << "[SlaveCommunicator] No connection exists";
        return;
    }
    if(openMasterConnection->isOpen()){
        data.append("\r\n");
        openMasterConnection->write(data);
        qDebug() << "[SlaveCommunicator] Sent" << data;
    }else{
        qWarning() << "[SlaveCommunicator] Connection is not open, so I can't send data";
    }
}

void SlaveCommunicator::setupConnection(){
    if(openMasterConnection==0){
        openMasterConnection = tcpListener.nextPendingConnection();
        if(openMasterConnection->isOpen()){
            qDebug() << "[SlaveCommunicator] Communication is open";
            qDebug() << "[SlaveCommunicator] Remote address is:" <<
                        openMasterConnection->peerAddress() <<
                        ":" << openMasterConnection->peerPort();
            connect(openMasterConnection, SIGNAL(readyRead()), SLOT(readData()), Qt::UniqueConnection);
            connect(openMasterConnection, SIGNAL(disconnected()), SLOT(connectionClosed()), Qt::UniqueConnection);
            emit connectionEstablished();
        }else{
            qWarning() << "[SlaveCommunicator] Not able to open connection";
        }
    }else{
        QTcpSocket *tmp = tcpListener.nextPendingConnection();
        qWarning() << "[SlaveCommunicator] You cannot be the slave of two masters! You will like one more than the other or be more loyal to one than the other. (Mat 6:24a)";
        tmp->close();
        tmp->deleteLater();
    }
}

void SlaveCommunicator::readData(){
    QString data = openMasterConnection->readLine();
    data.replace('\n', "");
    data.replace('\r', "");
    if(data.startsWith("#") && data.endsWith("##")){
        qDebug() << "[SlaveCommunicator] Valid data received: " << data;
        emit validDataReceived(data);
    }else{
        qWarning() << "[SlaveCommunicator] Unvalid data received: " << data;
    }
}

void SlaveCommunicator::connectionClosed(){
    qDebug() << "[SlaveCommunicator] Connection closed by remote host";
    openMasterConnection->deleteLater();
    openMasterConnection=0;
}
